package com.lgc.demo.recursion;

/**
 * 计算num和n次方
 */
public class Calculate1 {

    /**
     * 二分法 该算法的时间复杂度为O(lgn)
     *
     * @param num
     * @param n
     * @return
     */
    private double powerWithExponent(double num, long n) {
        if (0 == n) {
            return 1;
        } else if (1 == n) {
            return num;
        } else {
            if (n % 2 == 1) {
                double number = powerWithExponent(num, n / 2);
                return number * number * num;
            } else {
                double number = powerWithExponent(num, n / 2);
                return number * number;
            }
        }
    }

    /**
     * 笨方法，该算法的时间复杂度为O(N)
     */
    private double powerWithExponent3(double base, int absExponent) {
        double result = 1.0;
        for (int i = 1; i <= absExponent; ++i) {
            result *= base;
        }
        return result;
    }

    /**
     * 主方法
     *
     * @param base
     * @param exponent
     * @return
     */
    public double Power(double base, int exponent) {
        // 当底数为0，指数为负数时，则抛出异常或者返回0.0
        if (equal(base, 0) && exponent < 0) {
            return 0.0;
        }

        // 先对指数进行取绝对值计算
        int absExponent = Math.abs(exponent);
        double result = powerWithExponent(base, absExponent);
        //double result = powerWithExponent3(base, absExponent);

        // 判断如果传入的指数是负数，进行取反，否则直接返回
        if (exponent < 0) {
            result = 1.0 / result;
        }
        return result;
    }

    // 判断两个double类型的数值是否相等
    public boolean equal(double num1, double num2) {
        if ((num1 - num2 > -0.0000001) && (num1 - num2 < 0.0000001)) {
            return true;
        } else {
            return false;
        }
    }

    public static void main(String[] args) {
        Calculate1 calculate = new Calculate1();
        double result = calculate.Power(5, 5);

        int a = 0;
    }
}
